# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.


"""
An simple IRC bot - listens a channel's events to and reacts.
Configuration is set by twistbotconfig.py

To start, simply

  $ python ircBot.py

"""


# twisted imports
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
#from twisted.python import log

# config import
import twistbotconf

# system imports
import time, sys, random


class IrcBot(irc.IRCClient):
    """An IRC bot."""

    operpass = twistbotconf.password
    nickname = twistbotconf.nickname
    response = twistbotconf.response
    
    def connectionMade(self):
        print "Connection made!"
        irc.IRCClient.connectionMade(self)

    def connectionLost(self, reason):
        print "Connection Lost!"
        irc.IRCClient.connectionLost(self, reason)
    # callbacks for events

    def signedOn(self):
        """Called when bot has succesfully signed on to server."""
        print "Signed on!"
        self.join(self.factory.channel)

    def joined(self, channel):
        """This will get called when the bot joins the channel."""
        print "Joined %s" %channel

    def privmsg(self, user, channel, msg):
        print ">>> %s" %msg
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]
        response = self.response
        
        # Check to see if they're sending me a private message
        if channel == self.nickname:
            if msg == "quit-%s" %self.operpass:
                self.quit()
            msg = "It isn't nice to whisper!  Play nice with the group."
            self.msg(user, msg)
            return

        # Otherwise check to see if it is a message directed at me
        if msg.startswith(self.nickname + ":"):
            msg = msg.split(" ")[-1]
            if msg == "part-%s" %self.operpass:
                self.leave(self, channel)
            elif msg == "quit-%s" %self.operpass:
                self.quit()
            else:
                try:
                    msg = response[msg]
                    self.msg(channel, msg)
                except KeyError:
                    self.msg(channel, "I dont know that")

    def action(self, user, channel, msg):
        """This will get called when the bot sees someone do an action."""
        #user = user.split('!', 1)[0]
        #self.logger.log("* %s %s" % (user, msg))

    # irc callbacks

    def irc_NICK(self, prefix, params):
        """Called when an IRC user changes their nickname."""
        old_nick = prefix.split('!')[0]
        new_nick = params[0]
        #self.logger.log("%s is now known as %s" % (old_nick, new_nick))
    

    # For fun, override the method that determines how a nickname is changed on
    # collisions. The default method appends an underscore.
    def alterCollidedNick(self, nickname):
        """
        Generate an altered version of a nickname that caused a collision in an
        effort to create an unused related name for subsequent registration.
        """
        return nickname + '^'



class IrcBotFactory(protocol.ClientFactory):
    """A factory for IrcBots.

    A new protocol instance will be created each time we connect to the server.
    """

    # the class of the protocol to build when new connection is made
    protocol = IrcBot

    def __init__(self):
        self.channel = twistbotconf.channel

    def clientConnectionLost(self, connector, reason):
        """If we get disconnected, reconnect to server."""
        r = str(reason)
        print r
        if "cleanly" in r:
            reactor.stop()
            #sys.exit()
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "connection failed:", reason
        reactor.stop()


if __name__ == '__main__':
    
    # create factory protocol and application
    print "Creating Factory"
    f = IrcBotFactory()
    print "\tDone"

    # connect factory to this host and port
    print "Connection factory to host and port"
    reactor.connectTCP("irc.freenode.net", 6667, f)#twistbotconf.server, twistbotconf.port, f)
    print "\tDone"

    # run bot
    print "Running Reactor"
    reactor.run()
